# coding=utf-8


from qtpy import QtWidgets, QtCore, QtGui



class PopoverWidget(QtWidgets.QWidget):
    def __init__(self, parent=None) -> None:
        super(PopoverWidget, self).__init__(parent=parent)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.__start_x = 10
        self.__triangle_height = 30
        self.__triangle_width = 30
        self.__offset = 0
        self.__shadow_width = 5
        self.__border_radius = 20
        self.__is_hidden = False
        self.__bg_color = QtCore.Qt.white

        self.__main_layout = QtWidgets.QHBoxLayout(self)
        self.__main_layout.setContentsMargins(self.__shadow_width, self.__shadow_width + self.__triangle_height, self.__shadow_width, self.__shadow_width)

        effect = QtWidgets.QGraphicsDropShadowEffect(self)
        effect.setOffset(0,0)
        effect.setColor(QtCore.Qt.black)
        effect.setBlurRadius(self.__shadow_width)
        self.setGraphicsEffect(effect)
        self.setFixedSize(150, 200)

    def set_background_color(self, color):
        self.__bg_color = QtGui.QColor(*color)

    def set_triangle_hidden(self, status):
        self.__is_hidden = status

    def set_border_radius(self, in_radius):
        self.__border_radius = abs(in_radius)

    def set_triangle_start(self, in_x):
        self.__start_x = abs(in_x)

    def set_triangle_size(self, in_width, in_height):
        self.__triangle_height =  abs(in_height) if abs(in_height) < 60 else 60
        max_w = self.width() - 2*(self.__shadow_width + self.__border_radius)
        if abs(in_width) > max_w:
            self.__triangle_width = max_w
        else:
            self.__triangle_width = abs(in_width)

    def set_offset(self, in_offset):
        self.__offset = in_offset

    def set_center_widget(self, in_widget):
        self.__main_layout.addWidget(in_widget)

    def __get_first_point(self):
        max_x = self.width() - (self.__shadow_width + self.__border_radius + self.__triangle_width)
        _x = self.__shadow_width + self.__border_radius + self.__start_x
        if _x > max_x:
            _x = max_x
        _y = self.__triangle_height + self.__shadow_width
        return QtCore.QPoint(_x, _y)

    def __get_mid_point(self):
        max_x = self.width() - (self.__shadow_width + self.__border_radius + self.__triangle_width)
        min_x = self.__shadow_width + self.__border_radius
        if self.__offset == 0:
            _x = self.__shadow_width + self.__border_radius + self.__start_x + self.__triangle_width / 2
        else:
            _x = self.__shadow_width + self.__border_radius + self.__start_x + self.__triangle_width / 2 + self.__offset
        if _x > max_x:
            _x = max_x
        if _x < min_x:
            _x = min_x
        _y = self.__shadow_width
        return QtCore.QPoint(_x, _y)

    def __get_end_point(self):
        max_x = self.width() - (self.__shadow_width + self.__border_radius)
        _x = self.__shadow_width + self.__border_radius + self.__start_x + self.__triangle_width
        if _x > max_x:
            _x = max_x
        _y = self.__triangle_height + self.__shadow_width
        return QtCore.QPoint(_x, _y)

    def paintEvent(self, event) -> None:
        # if not self.__is_hidden:
        painter = QtGui.QPainter(self)
        painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
        painter.setPen(QtCore.Qt.NoPen)
        painter.setBrush(self.__bg_color)
        poly = QtGui.QPolygon()
        poly << self.__get_first_point()
        poly << self.__get_mid_point()
        poly << self.__get_end_point()
        draw_path = QtGui.QPainterPath()
        draw_path.addRoundedRect(
            QtCore.QRect(
                self.__shadow_width,
                self.__triangle_height + self.__shadow_width,
                self.width() - self.__shadow_width*2,
                self.height() - self.__shadow_width*2 - self.__triangle_height
            ),
            self.__border_radius,
            self.__border_radius
        )
        draw_path.addPolygon(poly)
        painter.drawPath(draw_path)
        painter.end()
        
        return super(PopoverWidget, self).paintEvent(event)
